package eu.epfc.dnet.mastermind.controller;

import eu.epfc.dnet.mastermind.model.beans.GameBean;
import eu.epfc.dnet.mastermind.model.beans.User;
import eu.epfc.dnet.mastermind.services.UserManager;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author Pierre Buvé & Nicolas Van Damme
 */
@Controller
public class LoginController {

    private UserManager userManager;

    /**
     * Injection du service Usermanager
     * @param userManager 
     */
    @Autowired
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }

    /**
     * Methode appellée lors de l'appel de la page login.htm via une requete de type GET
     * 
     * @param request
     * @param model
     * @return 
     */
    @RequestMapping(value ="/login.htm", method = RequestMethod.GET)
    protected ModelAndView displayLoginPage(HttpServletRequest request, ModelMap model) {
        ModelAndView modelAndView;
        if (request.getSession().getAttribute("username") != null) {
            // Si le paramètre username est stocké dans la session, demande directement l'affichage du dashboard utilisateur.
            String decoButton = "Déconnecter " + request.getSession().getAttribute("username");
            model.addAttribute("decobutton", decoButton);

            User user = new User();
            user.setUsername(request.getSession().getAttribute("username").toString());
            populateModelForUser(user, model);


            modelAndView = new ModelAndView("dashboard", "model", model);
        } else {

            modelAndView = new ModelAndView("login", "model", model);
        }

        return modelAndView;
    }

    /**
     * Methode appellée lors de l'appel de la page login.htm via une requete de type POST
     * @param request
     * @param model
     * @return 
     */
    @RequestMapping(value = "/login.htm", method = RequestMethod.POST)
    public ModelAndView sendLoggedToDashboard(HttpServletRequest request, ModelMap model) {

        // Récupère les infos du formulaire
        String login = request.getParameter("login");
        String password = request.getParameter("password");

        // Creation de l'utilisateur en mémoire
        User user = new User();
        user.setUsername(login);
        user.setPassword(password);

        // Vérifie que les 2 champs sont completés
        String errorMessage;

        if (login.equals("")) {
            errorMessage = "[ERREUR] Le champ 'Identifiant' est requis !";
            model.addAttribute("errormessage", errorMessage);
            return new ModelAndView("login", "model", model);
        } else if (password.equals("")) {
            errorMessage = "[ERREUR] Le champ 'Mot de passe' est requis !";
            model.addAttribute("errormessage", errorMessage);
            return new ModelAndView("login", "model", model);
        } else {

            // Verifie si l'user est dans la DB et que le password est correct
            if (!userManager.isUsernameInDatabase(login)) {
                errorMessage = "[ERREUR] Utilisateur inconnu !";
                model.addAttribute("errormessage", errorMessage);
                return new ModelAndView("login", "model", model);
            } else if (!userManager.isPasswordOK(user)) {
                errorMessage = "[ERREUR] Mot de passe incorrect !";
                model.addAttribute("errormessage", errorMessage);
                return new ModelAndView("login", "model", model);
            } else {

                populateModelForUser(user, model);

                request.getSession().setAttribute("username", user.getUsername());
                String decoButton = "Déconnecter " + request.getSession().getAttribute("username");
                model.addAttribute("decobutton", decoButton);


                // renvoie la page
                return new ModelAndView("dashboard", "model", model);
            }
        }

    }

    /**
     * Retourne le meilleur temps de l'utilisateur.
     * @param gameVictoryUser
     * @return 
     */
    private String getBestTimeUser(List<GameBean> gameVictoryUser) {

        Iterator<GameBean> i = gameVictoryUser.iterator();
        int bestTime = Integer.MAX_VALUE;
        while (i.hasNext()) {

            GameBean temp = i.next();
            if ((bestTime > temp.getDuration()) && (temp.getDuration() != 0)) {
                bestTime = temp.getDuration();
            }
        }
        if (bestTime == Integer.MAX_VALUE) {
            return "Pas de meilleur temps";
        } else {
            return bestTime + " secondes";
        }
    }

    /**
     * Peuple le modele selon l'utilisateur recu en paramètre
     * @param user
     * @param model
     * @return 
     */
    private ModelMap populateModelForUser(User user, ModelMap model) {

        List<GameBean> gameVictoryUser;
        List<GameBean> gameDefeatUser;
        List<GameBean> gameNewUser;
        List<GameBean> gamePlayingUser;

        int nbrVertUserUsed;
        int nbrRougeUserUsed;
        int nbrBleuUserUsed;
        int nbrJauneUserUsed;
        int nbrOrangeUserUsed;
        int nbrMauveUserUsed;
        int nbrNoirUserUsed;
        int nbrBlancUserUsed;
        
        // on récupère les valeurs auprès des services concernés.

        nbrVertUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "vert");
        nbrRougeUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "rouge");
        nbrBlancUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "blanc");
        nbrBleuUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "bleu");

        nbrJauneUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "jaune");
        nbrMauveUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "mauve");
        nbrNoirUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "noir");
        nbrOrangeUserUsed = userManager.getNbrColorUsedForUser(user.getUsername(), "orange");

        gameVictoryUser = userManager.getGameListForUserByStatus(user.getUsername(), "VICTORY");
        gameDefeatUser = userManager.getGameListForUserByStatus(user.getUsername(), "DEFEAT");
        gameNewUser = userManager.getGameListForUserByStatus(user.getUsername(), "NEW");
        gamePlayingUser = userManager.getGameListForUserByStatus(user.getUsername(), "PLAYING");

        // on ajoute les valeurs au model.
        
        model.addAttribute(user);

        model.addAttribute("nbrVictoryUser", gameVictoryUser.size());
        model.addAttribute("nbrDefeatUser", gameDefeatUser.size());
        model.addAttribute("nbrGameUser", (gameDefeatUser.size() + gameVictoryUser.size() + gameNewUser.size() + gamePlayingUser.size()));
        model.addAttribute("bestTimeUser", getBestTimeUser(gameVictoryUser));

        model.addAttribute("nbrVertUserUsed", nbrVertUserUsed);
        model.addAttribute("nbrRougeUserUsed", nbrRougeUserUsed);
        model.addAttribute("nbrBlancUserUsed", nbrBlancUserUsed);
        model.addAttribute("nbrBleuUserUsed", nbrBleuUserUsed);

        model.addAttribute("nbrJauneUserUsed", nbrJauneUserUsed);
        model.addAttribute("nbrMauveUserUsed", nbrMauveUserUsed);
        model.addAttribute("nbrNoirUserUsed", nbrNoirUserUsed);
        model.addAttribute("nbrOrangeUserUsed", nbrOrangeUserUsed);

        List<GameBean> listGameBean = userManager.getGameListForUserByStatus(user.getUsername(), "PLAYING");

        for (int i = 0; i < listGameBean.size(); i++) {
            System.out.println("Game " + i + " : " + listGameBean.get(i).getId() + " - CurrentLine : " + listGameBean.get(i).getCurrentLine());
        }

        model.addAttribute("listgames", listGameBean);
        //on envoie le model.
        return model;
    }
}
